package solutions.ferpa.ztest.ent;

import java.sql.*;
import java.util.ArrayList;
import br.com.telescope.adsrt.dom.*;
import br.com.telescope.adsrt.lib.*;
import br.com.telescope.t2.exception.Severity;

/**
 * API de persistência de dados da entidade CRITERIO_APROVACAO_PLANO_ENSAIO
 * @author Gerado pelo Telescope
 */
public class EntCriterioAprovacaoPlanoEnsaio extends Entity {
    
    public final static String ENTITY_NAME = "ZTEST.CRITERIO_APROVACAO_PLANO_ENSAIO";
    public final static String TABLE_NAME = "CRITERIO_APROVACAO_PLANO_ENSAIO";
    
    // <editor-fold defaultstate="collapsed" desc="Contrutores e inicializacao">
    /**
     * Construtores
     */
    public EntCriterioAprovacaoPlanoEnsaio() {
        super();
        initialize();
    }
    
    public EntCriterioAprovacaoPlanoEnsaio(BaseRuntime ctx) {
        super();
        initialize(ctx);
    }
    
    @Override
    public String getPrimaryKeyColumn() {
        return "ID";
    }
    
    @Override
    public void initialize(BaseRuntime ctx) {
        super.initialize(ctx);
        initialize();
    }
    
    public void initialize() {
        aId = new DomId(this,"ID", "Id"); 
        aId.setRequired(true);
        oId = new DomId();
        aPlanoEnsaioId = new DomId(this,"PLANO_ENSAIO_ID", "Plano de ensaio"); 
        aPlanoEnsaioId.setRequired(true);
        oPlanoEnsaioId = new DomId();
        aSequenciaValidacao = new DomInteger(this,"SEQUENCIA_VALIDACAO", "Sequência para validação de critérios"); 
        aSequenciaValidacao.setRequired(true);
        oSequenciaValidacao = new DomInteger();
        aCriterioAprovacaoId = new DomId(this,"CRITERIO_APROVACAO_ID", "Critério de aprovação"); 
        aCriterioAprovacaoId.setRequired(true);
        oCriterioAprovacaoId = new DomId();
        aDataRegistro = new DomDateTime(this,"DATA_REGISTRO", "Data do registro"); 
        aDataRegistro.setRequired(true);
        aDataRegistro.setDefaultValue("[SYSDATE]");
        oDataRegistro = new DomDateTime();
        ressetModified();
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="Atributos da entidade">
    
    // Id
    private DomId aId;
    private DomId oId;
    
    // Plano de ensaio
    private DomId aPlanoEnsaioId;
    private DomId oPlanoEnsaioId;
    
    // Sequência para validação de critérios
    private DomInteger aSequenciaValidacao;
    private DomInteger oSequenciaValidacao;
    
    // Critério de aprovação
    private DomId aCriterioAprovacaoId;
    private DomId oCriterioAprovacaoId;
    
    // Data do registro
    private DomDateTime aDataRegistro;
    private DomDateTime oDataRegistro;
    
    // <editor-fold defaultstate="collapsed" desc="Atributo ID">
    
    public EntCriterioAprovacaoPlanoEnsaio id(Long value) {
        setId(value);
        return this;
    }
    
    public void setId(DomId value) {
        if (value == null || value.isNull()) {
            nullifyId();
        } else {
            aId.setValue(value.getValue());
            if (aId.isModified()) {
                setModified(true);
            }
        }
    }
    
    public void setId(String value) {
        if (value == null) {
            nullifyId();
        } else {
            aId.setValue(value);
            if (aId.isModified()) {
                setModified(true);
            }
        }
    }
    
    public void setId(Long value) {
        aId.setValue(value);
        if (aId.isModified()) {
            setModified(true);
        }
    }
    
    public void setId(Object value) {
        aId.setValue(value);
        if (aId.isModified()) {
            setModified(true);
        }
    }
    
    public void nullifyId() {
        if (!aId.isNull()) {
            aId.setNull(true);
            setModified(true);
        }
    }
    
    public DomId getId() {
        return aId;
    }
    
    public DomId oldId() {
        return oId;
    }
    
    public Long valueOfId() {
        return aId.getValue();
    }
    
    public boolean isIdModified() {
        return aId.isModified();
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="Atributo PLANO_ENSAIO_ID">
    
    public EntCriterioAprovacaoPlanoEnsaio planoEnsaioId(Long value) {
        setPlanoEnsaioId(value);
        return this;
    }
    
    public void setPlanoEnsaioId(DomId value) {
        if (value == null || value.isNull()) {
            nullifyPlanoEnsaioId();
        } else {
            aPlanoEnsaioId.setValue(value.getValue());
            if (aPlanoEnsaioId.isModified()) {
                setModified(true);
            }
        }
    }
    
    public void setPlanoEnsaioId(String value) {
        if (value == null) {
            nullifyPlanoEnsaioId();
        } else {
            aPlanoEnsaioId.setValue(value);
            if (aPlanoEnsaioId.isModified()) {
                setModified(true);
            }
        }
    }
    
    public void setPlanoEnsaioId(Long value) {
        aPlanoEnsaioId.setValue(value);
        if (aPlanoEnsaioId.isModified()) {
            setModified(true);
        }
    }
    
    public void setPlanoEnsaioId(Object value) {
        aPlanoEnsaioId.setValue(value);
        if (aPlanoEnsaioId.isModified()) {
            setModified(true);
        }
    }
    
    public void nullifyPlanoEnsaioId() {
        if (!aPlanoEnsaioId.isNull()) {
            aPlanoEnsaioId.setNull(true);
            setModified(true);
        }
    }
    
    public DomId getPlanoEnsaioId() {
        return aPlanoEnsaioId;
    }
    
    public DomId oldPlanoEnsaioId() {
        return oPlanoEnsaioId;
    }
    
    public Long valueOfPlanoEnsaioId() {
        return aPlanoEnsaioId.getValue();
    }
    
    public boolean isPlanoEnsaioIdModified() {
        return aPlanoEnsaioId.isModified();
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="Atributo SEQUENCIA_VALIDACAO">
    
    public EntCriterioAprovacaoPlanoEnsaio sequenciaValidacao(Integer value) {
        setSequenciaValidacao(value);
        return this;
    }
    
    public void setSequenciaValidacao(DomInteger value) {
        if (value == null || value.isNull()) {
            nullifySequenciaValidacao();
        } else {
            aSequenciaValidacao.setValue(value.getValue());
            if (aSequenciaValidacao.isModified()) {
                setModified(true);
            }
        }
    }
    
    public void setSequenciaValidacao(String value) {
        if (value == null) {
            nullifySequenciaValidacao();
        } else {
            aSequenciaValidacao.setValue(value);
            if (aSequenciaValidacao.isModified()) {
                setModified(true);
            }
        }
    }
    
    public void setSequenciaValidacao(Integer value) {
        aSequenciaValidacao.setValue(value);
        if (aSequenciaValidacao.isModified()) {
            setModified(true);
        }
    }
    
    public void setSequenciaValidacao(Object value) {
        aSequenciaValidacao.setValue(value);
        if (aSequenciaValidacao.isModified()) {
            setModified(true);
        }
    }
    
    public void nullifySequenciaValidacao() {
        if (!aSequenciaValidacao.isNull()) {
            aSequenciaValidacao.setNull(true);
            setModified(true);
        }
    }
    
    public DomInteger getSequenciaValidacao() {
        return aSequenciaValidacao;
    }
    
    public DomInteger oldSequenciaValidacao() {
        return oSequenciaValidacao;
    }
    
    public Integer valueOfSequenciaValidacao() {
        return aSequenciaValidacao.getValue();
    }
    
    public boolean isSequenciaValidacaoModified() {
        return aSequenciaValidacao.isModified();
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="Atributo CRITERIO_APROVACAO_ID">
    
    public EntCriterioAprovacaoPlanoEnsaio criterioAprovacaoId(Long value) {
        setCriterioAprovacaoId(value);
        return this;
    }
    
    public void setCriterioAprovacaoId(DomId value) {
        if (value == null || value.isNull()) {
            nullifyCriterioAprovacaoId();
        } else {
            aCriterioAprovacaoId.setValue(value.getValue());
            if (aCriterioAprovacaoId.isModified()) {
                setModified(true);
            }
        }
    }
    
    public void setCriterioAprovacaoId(String value) {
        if (value == null) {
            nullifyCriterioAprovacaoId();
        } else {
            aCriterioAprovacaoId.setValue(value);
            if (aCriterioAprovacaoId.isModified()) {
                setModified(true);
            }
        }
    }
    
    public void setCriterioAprovacaoId(Long value) {
        aCriterioAprovacaoId.setValue(value);
        if (aCriterioAprovacaoId.isModified()) {
            setModified(true);
        }
    }
    
    public void setCriterioAprovacaoId(Object value) {
        aCriterioAprovacaoId.setValue(value);
        if (aCriterioAprovacaoId.isModified()) {
            setModified(true);
        }
    }
    
    public void nullifyCriterioAprovacaoId() {
        if (!aCriterioAprovacaoId.isNull()) {
            aCriterioAprovacaoId.setNull(true);
            setModified(true);
        }
    }
    
    public DomId getCriterioAprovacaoId() {
        return aCriterioAprovacaoId;
    }
    
    public DomId oldCriterioAprovacaoId() {
        return oCriterioAprovacaoId;
    }
    
    public Long valueOfCriterioAprovacaoId() {
        return aCriterioAprovacaoId.getValue();
    }
    
    public boolean isCriterioAprovacaoIdModified() {
        return aCriterioAprovacaoId.isModified();
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="Atributo DATA_REGISTRO">
    
    public EntCriterioAprovacaoPlanoEnsaio dataRegistro(java.sql.Timestamp value) {
        setDataRegistro(value);
        return this;
    }
    
    public void setDataRegistro(DomDateTime value) {
        if (value == null || value.isNull()) {
            nullifyDataRegistro();
        } else {
            aDataRegistro.setValue(value.getValue());
            if (aDataRegistro.isModified()) {
                setModified(true);
            }
        }
    }
    
    public void setDataRegistro(String value) {
        if (value == null) {
            nullifyDataRegistro();
        } else {
            aDataRegistro.setValue(value);
            if (aDataRegistro.isModified()) {
                setModified(true);
            }
        }
    }
    
    public void setDataRegistro(java.sql.Timestamp value) {
        aDataRegistro.setValue(value);
        if (aDataRegistro.isModified()) {
            setModified(true);
        }
    }
    
    public void setDataRegistro(Object value) {
        aDataRegistro.setValue(value);
        if (aDataRegistro.isModified()) {
            setModified(true);
        }
    }
    
    public void nullifyDataRegistro() {
        if (!aDataRegistro.isNull()) {
            aDataRegistro.setNull(true);
            setModified(true);
        }
    }
    
    public DomDateTime getDataRegistro() {
        return aDataRegistro;
    }
    
    public DomDateTime oldDataRegistro() {
        return oDataRegistro;
    }
    
    public java.sql.Timestamp valueOfDataRegistro() {
        return aDataRegistro.getValue();
    }
    
    public boolean isDataRegistroModified() {
        return aDataRegistro.isModified();
    }
    // </editor-fold>
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="getErrors">
    /**
     * Traduz um erro recebido do banco de dados para um AdsException
     */
    @Override
    public AdsException getErrors(String errorMsg, int transaction) {
        AdsException e;
        String msg = errorMsg.toUpperCase();
        
        if (transaction == DELETE_TRANSACTION) {
            e = new AdsException("ZTEST.CRITERIO_APROVACAO_PLANO_ENSAIO.GET_ERRORS_UNKNOWN",
                    AdsException.UNKNOWN,
                    "Erro não esperado: " + errorMsg);
        } else {
            if (msg.indexOf("UK_CAPLEN_CRITERIO") >= 0) {
                e = new AdsException("ZTEST.CRITERIO_APROVACAO_PLANO_ENSAIO.UK_CAPLEN_CRITERIO", 
                        Severity.ERROR,
                        "Registro duplicado! Critério de aprovação deve ser único para o plano de ensaio! Plano de ensaio ${PLANO_ENSAIO_ID}, Critério de aprovação ${CRITERIO_APROVACAO_ID} (UK_CAPLEN_CRITERIO)");
                return e;
            } else if (msg.indexOf("UK_CAPLEN_SEQUENCIA") >= 0) {
                e = new AdsException("ZTEST.CRITERIO_APROVACAO_PLANO_ENSAIO.UK_CAPLEN_SEQUENCIA", 
                        Severity.ERROR,
                        "Registro duplicado! Sequência do critério para validação deve ser único. Plano de ensaio ${PLANO_ENSAIO_ID}, Sequência para validação de critérios ${SEQUENCIA_VALIDACAO} (UK_CAPLEN_SEQUENCIA)");
                return e;
            } else if (msg.indexOf("FK_CAPLEN_CRITERIO_APROVACAO") >= 0) {
                e = new AdsException("ZTEST.CRITERIO_APROVACAO_PLANO_ENSAIO.FK_CAPLEN_CRITERIO_APROVACAO", 
                        Severity.ERROR,
                        "Registro não cadastrado para CRITERIO_APROVACAO! (FK_CAPLEN_CRITERIO_APROVACAO)");
                return e;
            } else if (msg.indexOf("FK_CAPLEN_PLANO_ENSAIO") >= 0) {
                e = new AdsException("ZTEST.CRITERIO_APROVACAO_PLANO_ENSAIO.FK_CAPLEN_PLANO_ENSAIO", 
                        Severity.ERROR,
                        "Registro não cadastrado para PLANO_ENSAIO! (FK_CAPLEN_PLANO_ENSAIO)");
                return e;
            } else if (msg.indexOf("PK_CAPLEN") >= 0) {
                e = new AdsException("ZTEST.CRITERIO_APROVACAO_PLANO_ENSAIO.PK_CAPLEN", 
                        Severity.ERROR,
                        "ID duplicado! (PK_CAPLEN)");
                return e;
            } else {
                e = new AdsException("ZTEST.CRITERIO_APROVACAO_PLANO_ENSAIO.GET_ERRORS_UNKNOWN",
                        AdsException.UNKNOWN,
                        "Erro não esperado: " + errorMsg);
            }
        }
        return e;
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="Entity Information">
    
    public String getEntityName() {
        return ENTITY_NAME;
    }
    
    public String getTableName() {
        return TABLE_NAME;
    }
    
    public String idSequenceName() {
        return "PK_SEQUENCE";
    }
    
    private ArrayList<Field> allAttributes;
    public ArrayList<Field> getAllAttributes() {
        if (allAttributes == null) {
            allAttributes = new ArrayList<Field>();
            allAttributes.add(aId);
            allAttributes.add(aPlanoEnsaioId);
            allAttributes.add(aSequenciaValidacao);
            allAttributes.add(aCriterioAprovacaoId);
            allAttributes.add(aDataRegistro);
        }
        return allAttributes;
    }
    
    /**
     * Retorna o valor da primeira UK da entidade
     * Se ela for composta, retorna a concatenação de toda a combinação
     * de atributos separados por um espaço.
     */
    public String valueOfUk() {
        return getPlanoEnsaioId().toString() +
                " " + getSequenciaValidacao().toString();
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="Relationships">
    
    
    public void findByPlanoEnsaioIdSequenciaValidacao(long planoEnsaioId, int sequenciaValidacao) throws AdsException {
        findBy(new String[] {"PLANO_ENSAIO_ID", "SEQUENCIA_VALIDACAO"},
                new Object[] {planoEnsaioId, sequenciaValidacao});
    }
    
    public void findByPlanoEnsaioIdCriterioAprovacaoId(long planoEnsaioId, long criterioAprovacaoId) throws AdsException {
        findBy(new String[] {"PLANO_ENSAIO_ID", "CRITERIO_APROVACAO_ID"},
                new Object[] {planoEnsaioId, criterioAprovacaoId});
    }
    
    private EntCriterioAprovacaoEnsaio eCriterioAprovacao;
    
    public EntCriterioAprovacaoEnsaio findCriterioAprovacao() throws AdsException {
        if (getCriterioAprovacaoId().isNull()) {
            return null;
        }
        if (eCriterioAprovacao == null || !valueOfCriterioAprovacaoId().equals(eCriterioAprovacao.valueOfId())) {
            eCriterioAprovacao = new EntCriterioAprovacaoEnsaio(ctx);
            eCriterioAprovacao.find(valueOfCriterioAprovacaoId());
        }
        return eCriterioAprovacao;
    }
    
    /**
     * Ativa o join desta entidade com CRITERIO_APROVACAO_ENSAIO
     * através do atributo CRITERIO_APROVACAO_ID
     */
    public EntCriterioAprovacaoEnsaio joinCriterioAprovacao() {
        return joinCriterioAprovacao(null);
    }
    public EntCriterioAprovacaoEnsaio joinCriterioAprovacao(String alias) {
        EntCriterioAprovacaoEnsaio entity = new EntCriterioAprovacaoEnsaio(ctx);
        if (alias != null) {
            entity.setAlias(alias);
        }
        Join newJoin = new Join(getCriterioAprovacaoId(), entity);
        entity.setJoinedBy(newJoin);
        this.join(newJoin);
        return entity;
    }
    
    public void findByCriterioAprovacao(long id, String sqlAppend) throws AdsException {
        find("select ID from CRITERIO_APROVACAO_PLANO_ENSAIO where CRITERIO_APROVACAO_ID = ? " + sqlAppend);
        sqlSetLong(1,id);
    }
    
    public void findByCriterioAprovacao(long id) throws AdsException {
        findByCriterioAprovacao(id,"");
    }
    
    public void findByCriterioAprovacao(Entity entidade) throws AdsException {
        findByCriterioAprovacao(entidade.valueOfId(),"");
    }
    
    public void findByCriterioAprovacao(Entity entidade, String sqlAppend) throws AdsException {
        findByCriterioAprovacao(entidade.valueOfId(),sqlAppend);
    }
    
    private EntPlanoExecucao ePlanoEnsaio;
    
    public EntPlanoExecucao findPlanoEnsaio() throws AdsException {
        if (getPlanoEnsaioId().isNull()) {
            return null;
        }
        if (ePlanoEnsaio == null || !valueOfPlanoEnsaioId().equals(ePlanoEnsaio.valueOfId())) {
            ePlanoEnsaio = new EntPlanoExecucao(ctx);
            ePlanoEnsaio.find(valueOfPlanoEnsaioId());
        }
        return ePlanoEnsaio;
    }
    
    /**
     * Ativa o join desta entidade com PLANO_EXECUCAO
     * através do atributo PLANO_ENSAIO_ID
     */
    public EntPlanoExecucao joinPlanoEnsaio() {
        return joinPlanoEnsaio(null);
    }
    public EntPlanoExecucao joinPlanoEnsaio(String alias) {
        EntPlanoExecucao entity = new EntPlanoExecucao(ctx);
        if (alias != null) {
            entity.setAlias(alias);
        }
        Join newJoin = new Join(getPlanoEnsaioId(), entity);
        entity.setJoinedBy(newJoin);
        this.join(newJoin);
        return entity;
    }
    
    public void findByPlanoEnsaio(long id, String sqlAppend) throws AdsException {
        find("select ID from CRITERIO_APROVACAO_PLANO_ENSAIO where PLANO_ENSAIO_ID = ? " + sqlAppend);
        sqlSetLong(1,id);
    }
    
    public void findByPlanoEnsaio(long id) throws AdsException {
        findByPlanoEnsaio(id,"");
    }
    
    public void findByPlanoEnsaio(Entity entidade) throws AdsException {
        findByPlanoEnsaio(entidade.valueOfId(),"");
    }
    
    public void findByPlanoEnsaio(Entity entidade, String sqlAppend) throws AdsException {
        findByPlanoEnsaio(entidade.valueOfId(),sqlAppend);
    }
    
    /**
     * Limpa os objetos normalizados da entidade
     */
    public void clearRelatedObjects() {
        eCriterioAprovacao = null;
        ePlanoEnsaio = null;
    }
    
    /**
     * Método que copia os valores dos atributos
     * para os valores respectivos old 
     */
    public void saveOldAtributes() {
        oDataRegistro.setValue(aDataRegistro);
        oSequenciaValidacao.setValue(aSequenciaValidacao);
        oCriterioAprovacaoId.setValue(aCriterioAprovacaoId);
        oPlanoEnsaioId.setValue(aPlanoEnsaioId);
        oId.setValue(aId);
    }
    
    /**
     * Método que retorna as regras da entidade
     * @return ArrayList com as regras ou null caso não existir nenhuma regra
     */
    public ArrayList getAllRules() {
        ArrayList<EntityRule> out = new ArrayList<EntityRule>();
        {
            PrimaryKeyRule rule = new PrimaryKeyRule();
            rule.setEntity(EntCriterioAprovacaoPlanoEnsaio.class);
            rule.setName("PK_CAPLEN");
            rule.setPkAttribute(new DomId("ID",""));
            out.add(rule);
        }
        {
            ForeignKeyRule rule = new ForeignKeyRule();
            rule.setEntity(EntCriterioAprovacaoPlanoEnsaio.class);
            rule.setAssociatedEntity(EntCriterioAprovacaoEnsaio.class);
            rule.setName("FK_CAPLEN_CRITERIO_APROVACAO");
            rule.addAttribute(new DomId("CRITERIO_APROVACAO_ID",""));
            out.add(rule);
        }
        {
            ForeignKeyRule rule = new ForeignKeyRule();
            rule.setEntity(EntCriterioAprovacaoPlanoEnsaio.class);
            rule.setAssociatedEntity(EntPlanoExecucao.class);
            rule.setName("FK_CAPLEN_PLANO_ENSAIO");
            rule.addAttribute(new DomId("PLANO_ENSAIO_ID",""));
            out.add(rule);
        }
        {
            UniqueKeyRule rule = new UniqueKeyRule();
            rule.setEntity(EntCriterioAprovacaoPlanoEnsaio.class);
            rule.setName("UK_CAPLEN_SEQUENCIA");
            rule.addAttribute(new DomId("PLANO_ENSAIO_ID",""));
            rule.addAttribute(new DomInteger("SEQUENCIA_VALIDACAO",""));
            out.add(rule);
        }
        {
            UniqueKeyRule rule = new UniqueKeyRule();
            rule.setEntity(EntCriterioAprovacaoPlanoEnsaio.class);
            rule.setName("UK_CAPLEN_CRITERIO");
            rule.addAttribute(new DomId("PLANO_ENSAIO_ID",""));
            rule.addAttribute(new DomId("CRITERIO_APROVACAO_ID",""));
            out.add(rule);
        }
        return out;
    }
    // </editor-fold>
    
    @Override
    protected void preInsert() throws AdsException {
        ajustarSituacaoPlanoExecucao(); //Ajustar situação do plano de execução
    }
    
    @Override
    public void fillDefaultValues() throws AdsException {
        if (aId.isNull()) {
            aId.setValue("" + ctx.getNextVal("pk_sequence"));
        }
        if (getDataRegistro().isNull()) {
            setDataRegistro(getDataRegistro().getDefaultValue());
        }
    }
    
    // <editor-fold defaultstate="collapsed" desc="Métodos customizados">
    
    /**
     * Regra de ação: Ajustar situação do plano de execução
     * 
     * Ao criar um novo CRITERIO_APROVACAO_PLANO_ENSAIO, o plano passa para 
     * pendente (apresentar msg para usuário)
     */
    private void ajustarSituacaoPlanoExecucao() throws AdsException {
        // <user-code id="21883094" parentId="21883085" hashcode="375b43bd" length="365">
        EntPlanoExecucao plano = findPlanoEnsaio();
        
        if (plano.getDataAprovado().isNotNull()) {
            plano.nullifyDataAprovado();
            plano.upd();
            
            ctx.pushError(ENTITY_NAME,
                    Severity.WARNING,
                    "A situação do plano de ensaio foi modificada! Execute a operação de aprovação para liberá-lo em testes de hidrômetros.");
        }
        plano.close();
        // </user-code>
    }
}
